---
title: Query Restrictions
description: "Limits, quotas, and permissions for analytics queries"
---

This page explains the restrictions, resource limits, and permissions for analytics queries.

### Only SELECT Allowed

Only `SELECT` queries are permitted. All other SQL statement types return a `query_not_supported` error.

**Allowed query patterns:**

- `SELECT` statements
- `WITH` (Common Table Expressions)
- `UNION`
- Subqueries
- Joins
- Aggregations
- Window functions

**Not allowed:** `INSERT`, `UPDATE`, `DELETE`, `DROP`, `ALTER`, `CREATE`, `TRUNCATE`, `GRANT`, `REVOKE`

### Table Access Control

Only explicitly allowed analytics tables are accessible. Any attempt to access tables not on the allow list (including `system.*` or `information_schema.*`) will return an `invalid_table` error.

### Function Allow List

Only explicitly approved functions are allowed. Any function not on this list will be rejected with an `invalid_function` error.

#### Allowed Functions

<AccordionGroup>

<Accordion title="Aggregates">
  `count`, `sum`, `avg`, `min`, `max`, `any`, `groupArray`, `groupUniqArray`,
  `uniq`, `uniqExact`, `quantile`, `countIf`
</Accordion>

<Accordion title="Date/Time">
  `now`, `now64`, `today`, `toDate`, `toDateTime`, `toDateTime64`,
  `toStartOfDay`, `toStartOfWeek`, `toStartOfMonth`, `toStartOfYear`,
  `toStartOfHour`, `toStartOfMinute`, `date_trunc`, `formatDateTime`,
  `fromUnixTimestamp64Milli`, `toUnixTimestamp64Milli`, `toIntervalDay`,
  `toIntervalWeek`, `toIntervalMonth`, `toIntervalYear`, `toIntervalHour`,
  `toIntervalMinute`, `toIntervalSecond`, `toIntervalMillisecond`,
  `toIntervalMicrosecond`, `toIntervalNanosecond`, `toIntervalQuarter`
</Accordion>

<Accordion title="String">
  `lower`, `upper`, `substring`, `concat`, `length`, `trim`, `startsWith`,
  `endsWith`
</Accordion>

<Accordion title="Math">`round`, `floor`, `ceil`, `abs`</Accordion>

<Accordion title="Conditional">`if`, `case`, `coalesce`</Accordion>

<Accordion title="Type Conversion">
  `toString`, `toInt32`, `toInt64`, `toFloat64`
</Accordion>

<Accordion title="Array">
  `has`, `hasAny`, `hasAll`, `arrayJoin`, `arrayFilter`
</Accordion>

</AccordionGroup>

<Note>
  If you need a function that's not listed, please contact us at
  [support@unkey.dev](mailto:support@unkey.dev) and we'll review it for
  inclusion.
</Note>

## Resource Limits

To ensure fair usage and prevent abuse, queries are subject to resource limits:

### Execution Limits

| Resource                        | Limit                 | Purpose                       |
| ------------------------------- | --------------------- | ----------------------------- |
| Max execution time              | 30 seconds            | Prevent long-running queries  |
| Max execution time (per window) | 1800 seconds (30 min) | Total execution time per hour |
| Max memory usage                | 1 GB                  | Prevent memory exhaustion     |
| Max result rows                 | 10 million            | Limit result set size         |

### Query Quotas

| Quota                 | Limit | Window   |
| --------------------- | ----- | -------- |
| Queries per workspace | 1000  | Per hour |

<Note>
  If you need higher limits for your use case, please contact us at
  [support@unkey.dev](mailto:support@unkey.dev) with details about your specific
  requirements and expected query volume.
</Note>

### Error Codes

When limits are exceeded, you'll receive specific error codes:

| Error Code                    | Description                       | Solution                                                   |
| ----------------------------- | --------------------------------- | ---------------------------------------------------------- |
| `query_execution_timeout`     | Query took longer than 30 seconds | Add more filters, reduce time range, use aggregated tables |
| `query_memory_limit_exceeded` | Query used more than 1GB memory   | Reduce result set size, add LIMIT clause, use aggregation  |
| `query_result_rows_exceeded`  | Query returned more than 10M rows | Add LIMIT clause, use aggregation, reduce time range       |
| `query_quota_exceeded`        | Exceeded 1000 queries per hour    | Wait for quota to reset, optimize query frequency          |
